'''
Constants for the g.py module

---------------------------------------------------------------------------
Copyright (c) 2011 Don Peterson
Contact:  gmail.com@someonesdad1

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Don Peterson's name may not be used to endorse or promote products
      derived from this software without specific prior written permission.

This software is provided by Don Peterson "as is" and any express or
implied warranties, including, but not limited to, the implied warranties
of merchantability and fitness for a particular purpose are disclaimed.  In
no event shall Don Peterson be liable for any direct, indirect, incidental,
special, exemplary, or consequential damages (including, but not limited
to, procurement of substitute goods or services; loss of use, data, or
profits; or business interruption) however caused and on any theory of
liability, whether in contract, strict liability, or tort (including
negligence or otherwise) arising in any way out of the use of this
software, even if advised of the possibility of such damage.
'''

class gException(Exception): pass
class NotImplemented(gException): pass

# We'll use a dictionary to keep track of the relationship between the
# integer and variable name (this can help with debugging).
varnames = {}

# Temporary variables and functions to make constants like enums
ix = 100

def Inc(name): # Helper function
    global ix, varnames
    ix = ix + 1
    varnames[ix] = name
    return ix

inf                          = 1e38  # Roughly +infinity for Postscript
no                           = Inc("no")
yes                          = Inc("yes")

landscape                    = Inc("landscape")
portrait                     = Inc("portrait")
seascape                     = Inc("seascape")
inversePortrait              = Inc("inversePortrait")
inverse_portrait             = inversePortrait

no_fill                      = Inc("no_fill")
solid_fill                   = Inc("solid_fill")
line_fill                    = Inc("line_fill")
gradient_fill                = Inc("gradient_fill")

solid_line                   = Inc("solid_line")
dashed                       = Inc("dashed")
dash_little_gap              = Inc("dash_little_gap")
dash_big_gap                 = Inc("dash_big_gap")
little_dash                  = Inc("little_dash")
dash_dot                     = Inc("dash_dot")
dash_dot_dot                 = Inc("dash_dot_dot")
scale_factor                 = Inc("scale_factor")

points                       = Inc("points")
inches                       = Inc("inches")
mm                           = Inc("mm")
cm                           = Inc("cm")
ft                           = Inc("ft")

cap_butt                     = Inc("cap_butt")
cap_round                    = Inc("cap_round")
cap_projecting               = Inc("cap_projecting")

join_miter                   = Inc("join_miter")
join_round                   = Inc("join_round")
join_bevel                   = Inc("join_bevel")

# The following fonts should be in every implementation
Sans                         = Inc("Sans")   # e.g., Helvetica, Arial
SansBold                     = Inc("SansBold")
SansItalic                   = Inc("SansItalic")
SansBoldItalic               = Inc("SansBoldItalic")
Serif                        = Inc("Serif")   # e.g., Times Roman
SerifBold                    = Inc("SerifBold")
SerifItalic                  = Inc("SerifItalic")
SerifBoldItalic              = Inc("SerifBoldItalic")
Courier                      = Inc("Courier")
CourierBold                  = Inc("CourierBold")
CourierBoldItalic            = Inc("CourierBoldItalic")
CourierItalic                = Inc("CourierItalic")
Symbol                       = Inc("Symbol")

# The following fonts are implementation dependent.  These are Postscript
# fonts for the HP 4050 LaserJet printer.
AlbertusExtraBold            = Inc("AlbertusExtraBold")
AlbertusMedium               = Inc("AlbertusMedium")
AntiqueOlive                 = Inc("AntiqueOlive")
AntiqueOliveBold             = Inc("AntiqueOliveBold")
AntiqueOliveItalic           = Inc("AntiqueOliveItalic")
Arial                        = Inc("Arial")
ArialBold                    = Inc("ArialBold")
ArialItalic                  = Inc("ArialItalic")
ArialBoldItalic              = Inc("ArialBoldItalic")
AvantGarde                   = Inc("AvantGarde")
AvantGardeBold               = Inc("AvantGardeBold")
AvantGardeItalic             = Inc("AvantGardeItalic")
AvantGardeBoldItalic         = Inc("AvantGardeBoldItalic")
Bookman                      = Inc("Bookman")
BookmanBold                  = Inc("BookmanBold")
BookmanItalic                = Inc("BookmanItalic")
BookmanBoldItalic            = Inc("BookmanBoldItalic")
Omega                        = Inc("Omega")
OmegaBold                    = Inc("OmegaBold")
OmegaItalic                  = Inc("OmegaItalic")
OmegaBoldItalic              = Inc("OmegaBoldItalic")
CGTimes                      = Inc("CGTimes")
CGTimesBold                  = Inc("CGTimesBold")
CGTimesItalic                = Inc("CGTimesItalic")
CGTimesBoldItalic            = Inc("CGTimesBoldItalic")
ClarendonCondensedBold       = Inc("ClarendonCondensedBold")
Coronet                      = Inc("Coronet")
GaramondAntiqua              = Inc("GaramondAntiqua")
GaramondHalbfett             = Inc("GaramondHalbfett")
GaramondKursiv               = Inc("GaramondKursiv")
GaramondKursivHalbfett       = Inc("GaramondKursivHalbfett")
Helvetica                    = Inc("Helvetica")
HelveticaBold                = Inc("HelveticaBold")
HelveticaBoldOblique         = Inc("HelveticaBoldOblique")
HelveticaOblique             = Inc("HelveticaOblique")
HelveticaNarrow              = Inc("HelveticaNarrow")
HelveticaNarrowBold          = Inc("HelveticaNarrowBold")
HelveticaNarrowBoldOblique   = Inc("HelveticaNarrowBoldOblique")
HelveticaNarrowOblique       = Inc("HelveticaNarrowOblique")
Marigold                     = Inc("Marigold")
Times                        = Inc("Times")
TimesBold                    = Inc("TimesBold")
TimesBoldItalic              = Inc("TimesBoldItalic")
TimesItalic                  = Inc("TimesItalic")
UniversMedium                = Inc("UniversMedium")
UniversMediumItalic          = Inc("UniversMediumItalic")
UniversBold                  = Inc("UniversBold")
UniversBoldItalic            = Inc("UniversBoldItalic")
UniversCondensedMedium       = Inc("UniversCondensedMedium")
UniversCondensedMediumItalic = Inc("UniversCondensedMediumItalic")
UniversCondensedBold         = Inc("UniversCondensedBold")
UniversCondensedBoldItalic   = Inc("UniversCondensedBoldItalic")
Dingbats                     = Inc("Dingbats")

# Color definitions.  These came from an X Windows rgb.txt file and
# were generated by the mkrgb.py script.
aliceblue              = (0.941, 0.973, 1.000)
antiquewhite           = (0.980, 0.922, 0.843)
antiquewhite1          = (1.000, 0.937, 0.859)
antiquewhite2          = (0.933, 0.875, 0.800)
antiquewhite3          = (0.804, 0.753, 0.690)
antiquewhite4          = (0.545, 0.514, 0.471)
aquamarine             = (0.196, 0.749, 0.757)
aquamarine1            = (0.498, 1.000, 0.831)
aquamarine2            = (0.463, 0.933, 0.776)
aquamarine3            = (0.400, 0.804, 0.667)
aquamarine4            = (0.271, 0.545, 0.455)
azure                  = (0.941, 1.000, 1.000)
azure1                 = (0.941, 1.000, 1.000)
azure2                 = (0.878, 0.933, 0.933)
azure3                 = (0.757, 0.804, 0.804)
azure4                 = (0.514, 0.545, 0.545)
beige                  = (0.961, 0.961, 0.863)
bisque                 = (1.000, 0.894, 0.769)
bisque1                = (1.000, 0.894, 0.769)
bisque2                = (0.933, 0.835, 0.718)
bisque3                = (0.804, 0.718, 0.620)
bisque4                = (0.545, 0.490, 0.420)
black                  = (0.000, 0.000, 0.000)
blanchedalmond         = (1.000, 0.922, 0.804)
blue                   = (0.000, 0.000, 1.000)
blue1                  = (0.000, 0.000, 1.000)
blue2                  = (0.000, 0.000, 0.933)
blue3                  = (0.000, 0.000, 0.804)
blue4                  = (0.000, 0.000, 0.545)
blueviolet             = (0.541, 0.169, 0.886)
brown                  = (0.647, 0.165, 0.165)
brown1                 = (1.000, 0.251, 0.251)
brown2                 = (0.933, 0.231, 0.231)
brown3                 = (0.804, 0.200, 0.200)
brown4                 = (0.545, 0.137, 0.137)
burlywood              = (0.871, 0.722, 0.529)
burlywood1             = (1.000, 0.827, 0.608)
burlywood2             = (0.933, 0.773, 0.569)
burlywood3             = (0.804, 0.667, 0.490)
burlywood4             = (0.545, 0.451, 0.333)
cadetblue              = (0.373, 0.573, 0.620)
cadetblue1             = (0.596, 0.961, 1.000)
cadetblue2             = (0.557, 0.898, 0.933)
cadetblue3             = (0.478, 0.773, 0.804)
cadetblue4             = (0.325, 0.525, 0.545)
chartreuse             = (0.498, 1.000, 0.000)
chartreuse1            = (0.498, 1.000, 0.000)
chartreuse2            = (0.463, 0.933, 0.000)
chartreuse3            = (0.400, 0.804, 0.000)
chartreuse4            = (0.271, 0.545, 0.000)
chocolate              = (0.824, 0.412, 0.118)
chocolate1             = (1.000, 0.498, 0.141)
chocolate2             = (0.933, 0.463, 0.129)
chocolate3             = (0.804, 0.400, 0.114)
chocolate4             = (0.545, 0.271, 0.075)
coral                  = (1.000, 0.447, 0.337)
coral1                 = (1.000, 0.447, 0.337)
coral2                 = (0.933, 0.416, 0.314)
coral3                 = (0.804, 0.357, 0.271)
coral4                 = (0.545, 0.243, 0.184)
cornflowerblue         = (0.133, 0.133, 0.596)
cornsilk               = (1.000, 0.973, 0.863)
cornsilk1              = (1.000, 0.973, 0.863)
cornsilk2              = (0.933, 0.910, 0.804)
cornsilk3              = (0.804, 0.784, 0.694)
cornsilk4              = (0.545, 0.533, 0.471)
cyan                   = (0.000, 1.000, 1.000)
cyan1                  = (0.000, 1.000, 1.000)
cyan2                  = (0.000, 0.933, 0.933)
cyan3                  = (0.000, 0.804, 0.804)
cyan4                  = (0.000, 0.545, 0.545)
darkgoldenrod          = (0.722, 0.525, 0.043)
darkgoldenrod1         = (1.000, 0.725, 0.059)
darkgoldenrod2         = (0.933, 0.678, 0.055)
darkgoldenrod3         = (0.804, 0.584, 0.047)
darkgoldenrod4         = (0.545, 0.396, 0.031)
darkgreen              = (0.000, 0.337, 0.176)
darkkhaki              = (0.741, 0.718, 0.420)
darkolivegreen         = (0.333, 0.337, 0.184)
darkolivegreen1        = (0.792, 1.000, 0.439)
darkolivegreen2        = (0.737, 0.933, 0.408)
darkolivegreen3        = (0.635, 0.804, 0.353)
darkolivegreen4        = (0.431, 0.545, 0.239)
darkorange             = (1.000, 0.549, 0.000)
darkorange1            = (1.000, 0.498, 0.000)
darkorange2            = (0.933, 0.463, 0.000)
darkorange3            = (0.804, 0.400, 0.000)
darkorange4            = (0.545, 0.271, 0.000)
darkorchid             = (0.545, 0.125, 0.545)
darkorchid1            = (0.749, 0.243, 1.000)
darkorchid2            = (0.698, 0.227, 0.933)
darkorchid3            = (0.604, 0.196, 0.804)
darkorchid4            = (0.408, 0.133, 0.545)
darksalmon             = (0.914, 0.588, 0.478)
darkseagreen           = (0.561, 0.737, 0.561)
darkseagreen1          = (0.757, 1.000, 0.757)
darkseagreen2          = (0.706, 0.933, 0.706)
darkseagreen3          = (0.608, 0.804, 0.608)
darkseagreen4          = (0.412, 0.545, 0.412)
darkslateblue          = (0.220, 0.294, 0.400)
darkslategray          = (0.184, 0.310, 0.310)
darkslategray1         = (0.592, 1.000, 1.000)
darkslategray2         = (0.553, 0.933, 0.933)
darkslategray3         = (0.475, 0.804, 0.804)
darkslategray4         = (0.322, 0.545, 0.545)
darkslategrey          = (0.184, 0.310, 0.310)
darkturquoise          = (0.000, 0.651, 0.651)
darkviolet             = (0.580, 0.000, 0.827)
deeppink               = (1.000, 0.078, 0.576)
deeppink1              = (1.000, 0.078, 0.576)
deeppink2              = (0.933, 0.071, 0.537)
deeppink3              = (0.804, 0.063, 0.463)
deeppink4              = (0.545, 0.039, 0.314)
deepskyblue            = (0.000, 0.749, 1.000)
deepskyblue1           = (0.000, 0.749, 1.000)
deepskyblue2           = (0.000, 0.698, 0.933)
deepskyblue3           = (0.000, 0.604, 0.804)
deepskyblue4           = (0.000, 0.408, 0.545)
dimgray                = (0.329, 0.329, 0.329)
dimgrey                = (0.329, 0.329, 0.329)
dodgerblue             = (0.118, 0.565, 1.000)
dodgerblue1            = (0.118, 0.565, 1.000)
dodgerblue2            = (0.110, 0.525, 0.933)
dodgerblue3            = (0.094, 0.455, 0.804)
dodgerblue4            = (0.063, 0.306, 0.545)
firebrick              = (0.557, 0.137, 0.137)
firebrick1             = (1.000, 0.188, 0.188)
firebrick2             = (0.933, 0.173, 0.173)
firebrick3             = (0.804, 0.149, 0.149)
firebrick4             = (0.545, 0.102, 0.102)
floralwhite            = (1.000, 0.980, 0.941)
forestgreen            = (0.314, 0.624, 0.412)
gainsboro              = (0.863, 0.863, 0.863)
ghostwhite             = (0.973, 0.973, 1.000)
gold                   = (0.855, 0.667, 0.000)
gold1                  = (1.000, 0.843, 0.000)
gold2                  = (0.933, 0.788, 0.000)
gold3                  = (0.804, 0.678, 0.000)
gold4                  = (0.545, 0.459, 0.000)
goldenrod              = (0.937, 0.875, 0.518)
goldenrod1             = (1.000, 0.757, 0.145)
goldenrod2             = (0.933, 0.706, 0.133)
goldenrod3             = (0.804, 0.608, 0.114)
goldenrod4             = (0.545, 0.412, 0.078)
gray                   = (0.494, 0.494, 0.494)
gray0                  = (0.000, 0.000, 0.000)
gray1                  = (0.012, 0.012, 0.012)
gray10                 = (0.102, 0.102, 0.102)
gray100                = (1.000, 1.000, 1.000)
gray11                 = (0.110, 0.110, 0.110)
gray12                 = (0.122, 0.122, 0.122)
gray13                 = (0.129, 0.129, 0.129)
gray14                 = (0.141, 0.141, 0.141)
gray15                 = (0.149, 0.149, 0.149)
gray16                 = (0.161, 0.161, 0.161)
gray17                 = (0.169, 0.169, 0.169)
gray18                 = (0.180, 0.180, 0.180)
gray19                 = (0.188, 0.188, 0.188)
gray2                  = (0.020, 0.020, 0.020)
gray20                 = (0.200, 0.200, 0.200)
gray21                 = (0.212, 0.212, 0.212)
gray22                 = (0.220, 0.220, 0.220)
gray23                 = (0.231, 0.231, 0.231)
gray24                 = (0.239, 0.239, 0.239)
gray25                 = (0.251, 0.251, 0.251)
gray26                 = (0.259, 0.259, 0.259)
gray27                 = (0.271, 0.271, 0.271)
gray28                 = (0.278, 0.278, 0.278)
gray29                 = (0.290, 0.290, 0.290)
gray3                  = (0.031, 0.031, 0.031)
gray30                 = (0.302, 0.302, 0.302)
gray31                 = (0.310, 0.310, 0.310)
gray32                 = (0.322, 0.322, 0.322)
gray33                 = (0.329, 0.329, 0.329)
gray34                 = (0.341, 0.341, 0.341)
gray35                 = (0.349, 0.349, 0.349)
gray36                 = (0.361, 0.361, 0.361)
gray37                 = (0.369, 0.369, 0.369)
gray38                 = (0.380, 0.380, 0.380)
gray39                 = (0.388, 0.388, 0.388)
gray4                  = (0.039, 0.039, 0.039)
gray40                 = (0.400, 0.400, 0.400)
gray41                 = (0.412, 0.412, 0.412)
gray42                 = (0.420, 0.420, 0.420)
gray43                 = (0.431, 0.431, 0.431)
gray44                 = (0.439, 0.439, 0.439)
gray45                 = (0.451, 0.451, 0.451)
gray46                 = (0.459, 0.459, 0.459)
gray47                 = (0.471, 0.471, 0.471)
gray48                 = (0.478, 0.478, 0.478)
gray49                 = (0.490, 0.490, 0.490)
gray5                  = (0.051, 0.051, 0.051)
gray50                 = (0.498, 0.498, 0.498)
gray51                 = (0.510, 0.510, 0.510)
gray52                 = (0.522, 0.522, 0.522)
gray53                 = (0.529, 0.529, 0.529)
gray54                 = (0.541, 0.541, 0.541)
gray55                 = (0.549, 0.549, 0.549)
gray56                 = (0.561, 0.561, 0.561)
gray57                 = (0.569, 0.569, 0.569)
gray58                 = (0.580, 0.580, 0.580)
gray59                 = (0.588, 0.588, 0.588)
gray6                  = (0.059, 0.059, 0.059)
gray60                 = (0.600, 0.600, 0.600)
gray61                 = (0.612, 0.612, 0.612)
gray62                 = (0.620, 0.620, 0.620)
gray63                 = (0.631, 0.631, 0.631)
gray64                 = (0.639, 0.639, 0.639)
gray65                 = (0.651, 0.651, 0.651)
gray66                 = (0.659, 0.659, 0.659)
gray67                 = (0.671, 0.671, 0.671)
gray68                 = (0.678, 0.678, 0.678)
gray69                 = (0.690, 0.690, 0.690)
gray7                  = (0.071, 0.071, 0.071)
gray70                 = (0.702, 0.702, 0.702)
gray71                 = (0.710, 0.710, 0.710)
gray72                 = (0.722, 0.722, 0.722)
gray73                 = (0.729, 0.729, 0.729)
gray74                 = (0.741, 0.741, 0.741)
gray75                 = (0.749, 0.749, 0.749)
gray76                 = (0.761, 0.761, 0.761)
gray77                 = (0.769, 0.769, 0.769)
gray78                 = (0.780, 0.780, 0.780)
gray79                 = (0.788, 0.788, 0.788)
gray8                  = (0.078, 0.078, 0.078)
gray80                 = (0.800, 0.800, 0.800)
gray81                 = (0.812, 0.812, 0.812)
gray82                 = (0.820, 0.820, 0.820)
gray83                 = (0.831, 0.831, 0.831)
gray84                 = (0.839, 0.839, 0.839)
gray85                 = (0.851, 0.851, 0.851)
gray86                 = (0.859, 0.859, 0.859)
gray87                 = (0.871, 0.871, 0.871)
gray88                 = (0.878, 0.878, 0.878)
gray89                 = (0.890, 0.890, 0.890)
gray9                  = (0.090, 0.090, 0.090)
gray90                 = (0.898, 0.898, 0.898)
gray91                 = (0.910, 0.910, 0.910)
gray92                 = (0.922, 0.922, 0.922)
gray93                 = (0.929, 0.929, 0.929)
gray94                 = (0.941, 0.941, 0.941)
gray95                 = (0.949, 0.949, 0.949)
gray96                 = (0.961, 0.961, 0.961)
gray97                 = (0.969, 0.969, 0.969)
gray98                 = (0.980, 0.980, 0.980)
gray99                 = (0.988, 0.988, 0.988)
green                  = (0.000, 1.000, 0.000)
green1                 = (0.000, 1.000, 0.000)
green2                 = (0.000, 0.933, 0.000)
green3                 = (0.000, 0.804, 0.000)
green4                 = (0.000, 0.545, 0.000)
greenyellow            = (0.678, 1.000, 0.184)
grey                   = (0.494, 0.494, 0.494)
grey0                  = (0.000, 0.000, 0.000)
grey1                  = (0.012, 0.012, 0.012)
grey10                 = (0.102, 0.102, 0.102)
grey100                = (1.000, 1.000, 1.000)
grey11                 = (0.110, 0.110, 0.110)
grey12                 = (0.122, 0.122, 0.122)
grey13                 = (0.129, 0.129, 0.129)
grey14                 = (0.141, 0.141, 0.141)
grey15                 = (0.149, 0.149, 0.149)
grey16                 = (0.161, 0.161, 0.161)
grey17                 = (0.169, 0.169, 0.169)
grey18                 = (0.180, 0.180, 0.180)
grey19                 = (0.188, 0.188, 0.188)
grey2                  = (0.020, 0.020, 0.020)
grey20                 = (0.200, 0.200, 0.200)
grey21                 = (0.212, 0.212, 0.212)
grey22                 = (0.220, 0.220, 0.220)
grey23                 = (0.231, 0.231, 0.231)
grey24                 = (0.239, 0.239, 0.239)
grey25                 = (0.251, 0.251, 0.251)
grey26                 = (0.259, 0.259, 0.259)
grey27                 = (0.271, 0.271, 0.271)
grey28                 = (0.278, 0.278, 0.278)
grey29                 = (0.290, 0.290, 0.290)
grey3                  = (0.031, 0.031, 0.031)
grey30                 = (0.302, 0.302, 0.302)
grey31                 = (0.310, 0.310, 0.310)
grey32                 = (0.322, 0.322, 0.322)
grey33                 = (0.329, 0.329, 0.329)
grey34                 = (0.341, 0.341, 0.341)
grey35                 = (0.349, 0.349, 0.349)
grey36                 = (0.361, 0.361, 0.361)
grey37                 = (0.369, 0.369, 0.369)
grey38                 = (0.380, 0.380, 0.380)
grey39                 = (0.388, 0.388, 0.388)
grey4                  = (0.039, 0.039, 0.039)
grey40                 = (0.400, 0.400, 0.400)
grey41                 = (0.412, 0.412, 0.412)
grey42                 = (0.420, 0.420, 0.420)
grey43                 = (0.431, 0.431, 0.431)
grey44                 = (0.439, 0.439, 0.439)
grey45                 = (0.451, 0.451, 0.451)
grey46                 = (0.459, 0.459, 0.459)
grey47                 = (0.471, 0.471, 0.471)
grey48                 = (0.478, 0.478, 0.478)
grey49                 = (0.490, 0.490, 0.490)
grey5                  = (0.051, 0.051, 0.051)
grey50                 = (0.498, 0.498, 0.498)
grey51                 = (0.510, 0.510, 0.510)
grey52                 = (0.522, 0.522, 0.522)
grey53                 = (0.529, 0.529, 0.529)
grey54                 = (0.541, 0.541, 0.541)
grey55                 = (0.549, 0.549, 0.549)
grey56                 = (0.561, 0.561, 0.561)
grey57                 = (0.569, 0.569, 0.569)
grey58                 = (0.580, 0.580, 0.580)
grey59                 = (0.588, 0.588, 0.588)
grey6                  = (0.059, 0.059, 0.059)
grey60                 = (0.600, 0.600, 0.600)
grey61                 = (0.612, 0.612, 0.612)
grey62                 = (0.620, 0.620, 0.620)
grey63                 = (0.631, 0.631, 0.631)
grey64                 = (0.639, 0.639, 0.639)
grey65                 = (0.651, 0.651, 0.651)
grey66                 = (0.659, 0.659, 0.659)
grey67                 = (0.671, 0.671, 0.671)
grey68                 = (0.678, 0.678, 0.678)
grey69                 = (0.690, 0.690, 0.690)
grey7                  = (0.071, 0.071, 0.071)
grey70                 = (0.702, 0.702, 0.702)
grey71                 = (0.710, 0.710, 0.710)
grey72                 = (0.722, 0.722, 0.722)
grey73                 = (0.729, 0.729, 0.729)
grey74                 = (0.741, 0.741, 0.741)
grey75                 = (0.749, 0.749, 0.749)
grey76                 = (0.761, 0.761, 0.761)
grey77                 = (0.769, 0.769, 0.769)
grey78                 = (0.780, 0.780, 0.780)
grey79                 = (0.788, 0.788, 0.788)
grey8                  = (0.078, 0.078, 0.078)
grey80                 = (0.800, 0.800, 0.800)
grey81                 = (0.812, 0.812, 0.812)
grey82                 = (0.820, 0.820, 0.820)
grey83                 = (0.831, 0.831, 0.831)
grey84                 = (0.839, 0.839, 0.839)
grey85                 = (0.851, 0.851, 0.851)
grey86                 = (0.859, 0.859, 0.859)
grey87                 = (0.871, 0.871, 0.871)
grey88                 = (0.878, 0.878, 0.878)
grey89                 = (0.890, 0.890, 0.890)
grey9                  = (0.090, 0.090, 0.090)
grey90                 = (0.898, 0.898, 0.898)
grey91                 = (0.910, 0.910, 0.910)
grey92                 = (0.922, 0.922, 0.922)
grey93                 = (0.929, 0.929, 0.929)
grey94                 = (0.941, 0.941, 0.941)
grey95                 = (0.949, 0.949, 0.949)
grey96                 = (0.961, 0.961, 0.961)
grey97                 = (0.969, 0.969, 0.969)
grey98                 = (0.980, 0.980, 0.980)
grey99                 = (0.988, 0.988, 0.988)
honeydew               = (0.941, 1.000, 0.941)
honeydew1              = (0.941, 1.000, 0.941)
honeydew2              = (0.878, 0.933, 0.878)
honeydew3              = (0.757, 0.804, 0.757)
honeydew4              = (0.514, 0.545, 0.514)
hotpink                = (1.000, 0.412, 0.706)
hotpink1               = (1.000, 0.431, 0.706)
hotpink2               = (0.933, 0.416, 0.655)
hotpink3               = (0.804, 0.376, 0.565)
hotpink4               = (0.545, 0.227, 0.384)
indianred              = (0.420, 0.224, 0.224)
indianred1             = (1.000, 0.416, 0.416)
indianred2             = (0.933, 0.388, 0.388)
indianred3             = (0.804, 0.333, 0.333)
indianred4             = (0.545, 0.227, 0.227)
ivory                  = (1.000, 1.000, 0.941)
ivory1                 = (1.000, 1.000, 0.941)
ivory2                 = (0.933, 0.933, 0.878)
ivory3                 = (0.804, 0.804, 0.757)
ivory4                 = (0.545, 0.545, 0.514)
khaki                  = (0.702, 0.702, 0.494)
khaki1                 = (1.000, 0.965, 0.561)
khaki2                 = (0.933, 0.902, 0.522)
khaki3                 = (0.804, 0.776, 0.451)
khaki4                 = (0.545, 0.525, 0.306)
lavender               = (0.902, 0.902, 0.980)
lavenderblush          = (1.000, 0.941, 0.961)
lavenderblush1         = (1.000, 0.941, 0.961)
lavenderblush2         = (0.933, 0.878, 0.898)
lavenderblush3         = (0.804, 0.757, 0.773)
lavenderblush4         = (0.545, 0.514, 0.525)
lawngreen              = (0.486, 0.988, 0.000)
lemonchiffon           = (1.000, 0.980, 0.804)
lemonchiffon1          = (1.000, 0.980, 0.804)
lemonchiffon2          = (0.933, 0.914, 0.749)
lemonchiffon3          = (0.804, 0.788, 0.647)
lemonchiffon4          = (0.545, 0.537, 0.439)
lightblue              = (0.690, 0.886, 1.000)
lightblue1             = (0.749, 0.937, 1.000)
lightblue2             = (0.698, 0.875, 0.933)
lightblue3             = (0.604, 0.753, 0.804)
lightblue4             = (0.408, 0.514, 0.545)
lightcoral             = (0.941, 0.502, 0.502)
lightcyan              = (0.878, 1.000, 1.000)
lightcyan1             = (0.878, 1.000, 1.000)
lightcyan2             = (0.820, 0.933, 0.933)
lightcyan3             = (0.706, 0.804, 0.804)
lightcyan4             = (0.478, 0.545, 0.545)
lightgoldenrod         = (0.933, 0.867, 0.510)
lightgoldenrod1        = (1.000, 0.925, 0.545)
lightgoldenrod2        = (0.933, 0.863, 0.510)
lightgoldenrod3        = (0.804, 0.745, 0.439)
lightgoldenrod4        = (0.545, 0.506, 0.298)
lightgoldenrodyellow   = (0.980, 0.980, 0.824)
lightgray              = (0.659, 0.659, 0.659)
lightgrey              = (0.659, 0.659, 0.659)
lightpink              = (1.000, 0.714, 0.757)
lightpink1             = (1.000, 0.682, 0.725)
lightpink2             = (0.933, 0.635, 0.678)
lightpink3             = (0.804, 0.549, 0.584)
lightpink4             = (0.545, 0.373, 0.396)
lightsalmon            = (1.000, 0.627, 0.478)
lightsalmon1           = (1.000, 0.627, 0.478)
lightsalmon2           = (0.933, 0.584, 0.447)
lightsalmon3           = (0.804, 0.506, 0.384)
lightsalmon4           = (0.545, 0.341, 0.259)
lightseagreen          = (0.125, 0.698, 0.667)
lightskyblue           = (0.529, 0.808, 0.980)
lightskyblue1          = (0.690, 0.886, 1.000)
lightskyblue2          = (0.643, 0.827, 0.933)
lightskyblue3          = (0.553, 0.714, 0.804)
lightskyblue4          = (0.376, 0.482, 0.545)
lightslateblue         = (0.518, 0.439, 1.000)
lightslategray         = (0.467, 0.533, 0.600)
lightslategrey         = (0.467, 0.533, 0.600)
lightsteelblue         = (0.486, 0.596, 0.827)
lightsteelblue1        = (0.792, 0.882, 1.000)
lightsteelblue2        = (0.737, 0.824, 0.933)
lightsteelblue3        = (0.635, 0.710, 0.804)
lightsteelblue4        = (0.431, 0.482, 0.545)
lightyellow            = (1.000, 1.000, 0.878)
lightyellow1           = (1.000, 1.000, 0.878)
lightyellow2           = (0.933, 0.933, 0.820)
lightyellow3           = (0.804, 0.804, 0.706)
lightyellow4           = (0.545, 0.545, 0.478)
limegreen              = (0.000, 0.686, 0.078)
linen                  = (0.980, 0.941, 0.902)
magenta                = (1.000, 0.000, 1.000)
magenta1               = (1.000, 0.000, 1.000)
magenta2               = (0.933, 0.000, 0.933)
magenta3               = (0.804, 0.000, 0.804)
magenta4               = (0.545, 0.000, 0.545)
maroon                 = (0.561, 0.000, 0.322)
maroon1                = (1.000, 0.204, 0.702)
maroon2                = (0.933, 0.188, 0.655)
maroon3                = (0.804, 0.161, 0.565)
maroon4                = (0.545, 0.110, 0.384)
mediumaquamarine       = (0.000, 0.576, 0.561)
mediumblue             = (0.196, 0.196, 0.800)
mediumforestgreen      = (0.196, 0.506, 0.294)
mediumgoldenrod        = (0.820, 0.757, 0.400)
mediumorchid           = (0.741, 0.322, 0.741)
mediumorchid1          = (0.878, 0.400, 1.000)
mediumorchid2          = (0.820, 0.373, 0.933)
mediumorchid3          = (0.706, 0.322, 0.804)
mediumorchid4          = (0.478, 0.216, 0.545)
mediumpurple           = (0.576, 0.439, 0.859)
mediumpurple1          = (0.671, 0.510, 1.000)
mediumpurple2          = (0.624, 0.475, 0.933)
mediumpurple3          = (0.537, 0.408, 0.804)
mediumpurple4          = (0.365, 0.278, 0.545)
mediumseagreen         = (0.204, 0.467, 0.400)
mediumslateblue        = (0.416, 0.416, 0.553)
mediumspringgreen      = (0.137, 0.557, 0.137)
mediumturquoise        = (0.000, 0.824, 0.824)
mediumvioletred        = (0.835, 0.125, 0.475)
midnightblue           = (0.184, 0.184, 0.392)
mintcream              = (0.961, 1.000, 0.980)
mistyrose              = (1.000, 0.894, 0.882)
mistyrose1             = (1.000, 0.894, 0.882)
mistyrose2             = (0.933, 0.835, 0.824)
mistyrose3             = (0.804, 0.718, 0.710)
mistyrose4             = (0.545, 0.490, 0.482)
moccasin               = (1.000, 0.894, 0.710)
navajowhite            = (1.000, 0.871, 0.678)
navajowhite1           = (1.000, 0.871, 0.678)
navajowhite2           = (0.933, 0.812, 0.631)
navajowhite3           = (0.804, 0.702, 0.545)
navajowhite4           = (0.545, 0.475, 0.369)
navy                   = (0.137, 0.137, 0.459)
navyblue               = (0.137, 0.137, 0.459)
oldlace                = (0.992, 0.961, 0.902)
olivedrab              = (0.420, 0.557, 0.137)
olivedrab1             = (0.753, 1.000, 0.243)
olivedrab2             = (0.702, 0.933, 0.227)
olivedrab3             = (0.604, 0.804, 0.196)
olivedrab4             = (0.412, 0.545, 0.133)
orange                 = (1.000, 0.529, 0.000)
orange1                = (1.000, 0.647, 0.000)
orange2                = (0.933, 0.604, 0.000)
orange3                = (0.804, 0.522, 0.000)
orange4                = (0.545, 0.353, 0.000)
orangered              = (1.000, 0.271, 0.000)
orangered1             = (1.000, 0.271, 0.000)
orangered2             = (0.933, 0.251, 0.000)
orangered3             = (0.804, 0.216, 0.000)
orangered4             = (0.545, 0.145, 0.000)
orchid                 = (0.937, 0.518, 0.937)
orchid1                = (1.000, 0.514, 0.980)
orchid2                = (0.933, 0.478, 0.914)
orchid3                = (0.804, 0.412, 0.788)
orchid4                = (0.545, 0.278, 0.537)
palegoldenrod          = (0.933, 0.910, 0.667)
palegreen              = (0.451, 0.871, 0.471)
palegreen1             = (0.604, 1.000, 0.604)
palegreen2             = (0.565, 0.933, 0.565)
palegreen3             = (0.486, 0.804, 0.486)
palegreen4             = (0.329, 0.545, 0.329)
paleturquoise          = (0.686, 0.933, 0.933)
paleturquoise1         = (0.733, 1.000, 1.000)
paleturquoise2         = (0.682, 0.933, 0.933)
paleturquoise3         = (0.588, 0.804, 0.804)
paleturquoise4         = (0.400, 0.545, 0.545)
palevioletred          = (0.859, 0.439, 0.576)
palevioletred1         = (1.000, 0.510, 0.671)
palevioletred2         = (0.933, 0.475, 0.624)
palevioletred3         = (0.804, 0.408, 0.537)
palevioletred4         = (0.545, 0.278, 0.365)
papayawhip             = (1.000, 0.937, 0.835)
peachpuff              = (1.000, 0.855, 0.725)
peachpuff1             = (1.000, 0.855, 0.725)
peachpuff2             = (0.933, 0.796, 0.678)
peachpuff3             = (0.804, 0.686, 0.584)
peachpuff4             = (0.545, 0.467, 0.396)
peru                   = (0.804, 0.522, 0.247)
pink                   = (1.000, 0.710, 0.773)
pink1                  = (1.000, 0.710, 0.773)
pink2                  = (0.933, 0.663, 0.722)
pink3                  = (0.804, 0.569, 0.620)
pink4                  = (0.545, 0.388, 0.424)
plum                   = (0.773, 0.282, 0.608)
plum1                  = (1.000, 0.733, 1.000)
plum2                  = (0.933, 0.682, 0.933)
plum3                  = (0.804, 0.588, 0.804)
plum4                  = (0.545, 0.400, 0.545)
powderblue             = (0.690, 0.878, 0.902)
purple                 = (0.627, 0.125, 0.941)
purple1                = (0.608, 0.188, 1.000)
purple2                = (0.569, 0.173, 0.933)
purple3                = (0.490, 0.149, 0.804)
purple4                = (0.333, 0.102, 0.545)
red                    = (1.000, 0.000, 0.000)
red1                   = (1.000, 0.000, 0.000)
red2                   = (0.933, 0.000, 0.000)
red3                   = (0.804, 0.000, 0.000)
red4                   = (0.545, 0.000, 0.000)
rosybrown              = (0.737, 0.561, 0.561)
rosybrown1             = (1.000, 0.757, 0.757)
rosybrown2             = (0.933, 0.706, 0.706)
rosybrown3             = (0.804, 0.608, 0.608)
rosybrown4             = (0.545, 0.412, 0.412)
royalblue              = (0.255, 0.412, 0.882)
royalblue1             = (0.282, 0.463, 1.000)
royalblue2             = (0.263, 0.431, 0.933)
royalblue3             = (0.227, 0.373, 0.804)
royalblue4             = (0.153, 0.251, 0.545)
saddlebrown            = (0.545, 0.271, 0.075)
salmon                 = (0.914, 0.588, 0.478)
salmon1                = (1.000, 0.549, 0.412)
salmon2                = (0.933, 0.510, 0.384)
salmon3                = (0.804, 0.439, 0.329)
salmon4                = (0.545, 0.298, 0.224)
sandybrown             = (0.957, 0.643, 0.376)
seagreen               = (0.322, 0.584, 0.518)
seagreen1              = (0.329, 1.000, 0.624)
seagreen2              = (0.306, 0.933, 0.580)
seagreen3              = (0.263, 0.804, 0.502)
seagreen4              = (0.180, 0.545, 0.341)
seashell               = (1.000, 0.961, 0.933)
seashell1              = (1.000, 0.961, 0.933)
seashell2              = (0.933, 0.898, 0.871)
seashell3              = (0.804, 0.773, 0.749)
seashell4              = (0.545, 0.525, 0.510)
sienna                 = (0.588, 0.322, 0.176)
sienna1                = (1.000, 0.510, 0.278)
sienna2                = (0.933, 0.475, 0.259)
sienna3                = (0.804, 0.408, 0.224)
sienna4                = (0.545, 0.278, 0.149)
skyblue                = (0.447, 0.624, 1.000)
skyblue1               = (0.529, 0.808, 1.000)
skyblue2               = (0.494, 0.753, 0.933)
skyblue3               = (0.424, 0.651, 0.804)
skyblue4               = (0.290, 0.439, 0.545)
slateblue              = (0.494, 0.533, 0.671)
slateblue1             = (0.514, 0.435, 1.000)
slateblue2             = (0.478, 0.404, 0.933)
slateblue3             = (0.412, 0.349, 0.804)
slateblue4             = (0.278, 0.235, 0.545)
slategray              = (0.439, 0.502, 0.565)
slategray1             = (0.776, 0.886, 1.000)
slategray2             = (0.725, 0.827, 0.933)
slategray3             = (0.624, 0.714, 0.804)
slategray4             = (0.424, 0.482, 0.545)
slategrey              = (0.439, 0.502, 0.565)
snow                   = (1.000, 0.980, 0.980)
snow1                  = (1.000, 0.980, 0.980)
snow2                  = (0.933, 0.914, 0.914)
snow3                  = (0.804, 0.788, 0.788)
snow4                  = (0.545, 0.537, 0.537)
springgreen            = (0.255, 0.675, 0.255)
springgreen1           = (0.000, 1.000, 0.498)
springgreen2           = (0.000, 0.933, 0.463)
springgreen3           = (0.000, 0.804, 0.400)
springgreen4           = (0.000, 0.545, 0.271)
steelblue              = (0.329, 0.439, 0.667)
steelblue1             = (0.388, 0.722, 1.000)
steelblue2             = (0.361, 0.675, 0.933)
steelblue3             = (0.310, 0.580, 0.804)
steelblue4             = (0.212, 0.392, 0.545)
tan                    = (0.871, 0.722, 0.529)
tan1                   = (1.000, 0.647, 0.310)
tan2                   = (0.933, 0.604, 0.286)
tan3                   = (0.804, 0.522, 0.247)
tan4                   = (0.545, 0.353, 0.169)
thistle                = (0.847, 0.749, 0.847)
thistle1               = (1.000, 0.882, 1.000)
thistle2               = (0.933, 0.824, 0.933)
thistle3               = (0.804, 0.710, 0.804)
thistle4               = (0.545, 0.482, 0.545)
tomato                 = (1.000, 0.388, 0.278)
tomato1                = (1.000, 0.388, 0.278)
tomato2                = (0.933, 0.361, 0.259)
tomato3                = (0.804, 0.310, 0.224)
tomato4                = (0.545, 0.212, 0.149)
transparent            = (0.000, 0.000, 0.004)
turquoise              = (0.098, 0.800, 0.875)
turquoise1             = (0.000, 0.961, 1.000)
turquoise2             = (0.000, 0.898, 0.933)
turquoise3             = (0.000, 0.773, 0.804)
turquoise4             = (0.000, 0.525, 0.545)
violet                 = (0.612, 0.243, 0.808)
violetred              = (0.953, 0.243, 0.588)
violetred1             = (1.000, 0.243, 0.588)
violetred2             = (0.933, 0.227, 0.549)
violetred3             = (0.804, 0.196, 0.471)
violetred4             = (0.545, 0.133, 0.322)
wheat                  = (0.961, 0.871, 0.702)
wheat1                 = (1.000, 0.906, 0.729)
wheat2                 = (0.933, 0.847, 0.682)
wheat3                 = (0.804, 0.729, 0.588)
wheat4                 = (0.545, 0.494, 0.400)
white                  = (1.000, 1.000, 1.000)
whitesmoke             = (0.961, 0.961, 0.961)
yellow                 = (1.000, 1.000, 0.000)
yellow1                = (1.000, 1.000, 0.000)
yellow2                = (0.933, 0.933, 0.000)
yellow3                = (0.804, 0.804, 0.000)
yellow4                = (0.545, 0.545, 0.000)
yellowgreen            = (0.196, 0.847, 0.220)

# Constants to identify graphics state (GS) elements
g_paper_size         = Inc("g_paper_size")
g_orientation        = Inc("g_orientation")
g_units              = Inc("g_units")
g_line               = Inc("g_line")
g_fill               = Inc("g_fill")
g_font               = Inc("g_font")
g_ctm                = Inc("g_ctm")
g_current_path       = Inc("g_current_path")
g_current_clip_path  = Inc("g_current_clip_path")
g_current_point      = Inc("g_current_point")
g_current_color      = Inc("g_current_color")
g_scale_line_width   = Inc("g_scale_line_width")
g_scale_font_size    = Inc("g_scale_font_size")

# Indexes into class changed flag & value
g_changed = 0
g_value   = 1

# Constants used to identify paper sizes
paper_letter         = Inc("paper_letter")
paper_legal          = Inc("paper_legal")
paper_ledger         = Inc("paper_ledger")  # 11x17
paper_A4             = Inc("paper_A4")

# Constants used to identify a subpath element
path_point           = Inc("path_point")
path_arc_ccw         = Inc("path_arc_ccw")
path_arc_cw          = Inc("path_arc_cw")
path_bezier          = Inc("path_bezier")

del ix
del Inc

UEL                  = "\033%-12345X"  # Used in PJL

# Convenience function to calculate ISO paper sizes.
def ISO_paper(n, format):
    '''Return a tuple of (width, height) for ISO paper sizes.  The
    dimensions are in points.  The format parameter must be "A", "B", or
    "C" and n must be an integer between 0 and 10.  The width and height
    are given in points.  The formulas are taken from
    http://www.cl.cam.ac.uk/~mgk25/iso-paper.html.
    '''
    import math
    if n < 0 or n > 10 or int(n) != n:
        raise Exception("n must be an integer >=  and <= 10")
    # The following formulas give the paper dimensions in m
    if format == "A":
        width  = math.pow(2, -1/4. - n/2.)
        height = math.pow(2,  1/4. - n/2.)
    elif format == "B":
        width  = math.pow(2,       - n/2.)
        height = math.pow(2,  1/2. - n/2.)
    elif format == "C":
        width  = math.pow(2, -1/8. - n/2.)
        height = math.pow(2,  3/8. - n/2.)
    else:
        raise Exception("Unrecognized ISO paper format")
    m_to_points = 2845.2756  # Conversion factor
    return (int(width*m_to_points), int(height*m_to_points))

#-----------------------------------------------------------------------------
# Dictionaries used to translate and validate values

paper_sizes = { # (width, height) in portrait mode in points
    paper_letter         : (8.5*72, 11.*72),
    paper_legal          : (8.5*72, 14.*72),
    paper_ledger         : (11.*72, 17.*72),
    paper_A4             : ISO_paper(4, "A"),
}

allowed_orientations = {  # Gives rotation angle
    portrait             : 0,
    seascape             : 90,
    inverse_portrait     : 180,
    landscape            : 270,
}

allowed_units = {  # Convenience array of scaling factors.  These factors
                   # convert back to the default Postscript units, which
                   # are points.
    points               : 1.0,
    inches               : 72.0,
    mm                   : 72.0/25.4,
    cm                   : 72.0/2.54,
    ft                   : 72.0*12,
}

allowed_fill_types = {
    no_fill              : no_fill,
    solid_fill           : solid_fill,
    line_fill            : line_fill,
    gradient_fill        : gradient_fill,
}

dashes = {  # Maps dash types to their Postscript setdash values.  These
            # sizes are in the Postscript default units, which are points.
            # The first number is the length of the first dash, the second
            # number is the width of the space, etc.
    solid_line           : [ ],
    dashed               : [10, 10],
    dash_little_gap      : [20, 4],
    dash_big_gap         : [1, 10],
    little_dash          : [4, 4],
    dash_dot             : [10, 2, 2, 2],
    dash_dot_dot         : [10, 2, 2, 2, 2, 2],
    scale_factor         : 1.0,   # Used to scale the dash sizes
}

line_caps = {
    cap_butt             : 0,
    cap_round            : 1,
    cap_projecting       : 2,
}

line_joins = {
    join_miter           : 0,
    join_round           : 1,
    join_bevel           : 2,
}

allowed_font_names = {
    Sans                         : "Helvetica",
    SansBold                     : "Helvetica-Bold",
    SansItalic                   : "Helvetica-Italic",
    SansBoldItalic               : "Helvetica-BoldItalic",
    Serif                        : "Times-Roman",
    SerifBold                    : "Times-Bold",
    SerifItalic                  : "Times-Oblique",
    SerifBoldItalic              : "Times-BoldOblique",

    AlbertusExtraBold            : "Albertus-ExtraBold",
    AlbertusMedium               : "Albertus-Medium",
    AntiqueOlive                 : "AntiqueOlive",
    AntiqueOliveBold             : "AntiqueOlive-Bold",
    AntiqueOliveItalic           : "AntiqueOlive-Italic",
    Arial                        : "Arial",
    ArialBold                    : "Arial-Bold",
    ArialItalic                  : "Arial-Italic",
    ArialBoldItalic              : "Arial-BoldItalic",
    AvantGarde                   : "AvantGarde-Book",
    AvantGardeBold               : "AvantGarde-Demi",
    AvantGardeItalic             : "AvantGarde-BookOblique",
    AvantGardeBoldItalic         : "AvantGarde-DemiOblique",
    Bookman                      : "Bookman-Light",
    BookmanBold                  : "Bookman-Demi",
    BookmanItalic                : "Bookman-LightItalic",
    BookmanBoldItalic            : "Bookman-DemiItalic",
    Omega                        : "CGOmega",
    OmegaBold                    : "CGOmega-Bold",
    OmegaItalic                  : "CGOmega-Italic",
    OmegaBoldItalic              : "CGOmega-BoldItalic",
    CGTimes                      : "CGTimes",
    CGTimesBold                  : "CGTimes-Bold",
    CGTimesItalic                : "CGTimes-Italic",
    CGTimesBoldItalic            : "CGTimes-BoldItalic",
    ClarendonCondensedBold       : "Clarendon-Condensed-Bold",
    Coronet                      : "Coronet",
    Courier                      : "Courier",
    CourierBold                  : "Courier-Bold",
    CourierBoldItalic            : "Courier-BoldItalic",
    CourierItalic                : "Courier-Italic",
    GaramondAntiqua              : "Garamond-Antiqua",
    GaramondHalbfett             : "Garamond-Halbfett",
    GaramondKursiv               : "Garamond-Kursiv",
    GaramondKursivHalbfett       : "Garamond-KursivHalbfett",
    Helvetica                    : "Helvetica",
    HelveticaBold                : "Helvetica-Bold",
    HelveticaBoldOblique         : "Helvetica-BoldOblique",
    HelveticaOblique             : "Helvetica-Oblique",
    HelveticaNarrow              : "Helvetica-Narrow",
    HelveticaNarrowBold          : "Helvetica-Narrow-Bold",
    HelveticaNarrowBoldOblique   : "Helvetica-Narrow-BoldOblique",
    HelveticaNarrowOblique       : "Helvetica-Narrow-Oblique",
    Marigold                     : "Marigold",
    Symbol                       : "Symbol",
    Times                        : "Times-Roman",
    TimesBold                    : "Times-Bold",
    TimesBoldItalic              : "Times-BoldItalic",
    TimesItalic                  : "Times-Italic",
    UniversMedium                : "Univers-Medium",
    UniversMediumItalic          : "Univers-MediumItalic",
    UniversBold                  : "Univers-Bold",
    UniversBoldItalic            : "Univers-BoldItalic",
    UniversCondensedMedium       : "Univers-Condensed-Medium",
    UniversCondensedMediumItalic : "Univers-Condensed-MediumItalic",
    UniversCondensedBold         : "Univers-Condensed-Bold",
    UniversCondensedBoldItalic   : "Univers-Condensed-BoldItalic",
    Dingbats                     : "ZapfDingbats",
}

# The ps dictionary is used to save a little space in the output Postscript
# file by aliasing the Postscript commands with single characters.  Of
# course, this makes the output file impossible to read easily, so you'll
# want to set translate_PS to no for debugging the Postscript output.

translate_PS = yes
ps = {
    "arc"           : "",
    "begin"         : "",
    "bind"          : "",
    "closepath"     : "",
    "colorimage"    : "",
    "currentmatrix" : "",
    "curveto"       : "",
    "dict"          : "",
    "div"           : "",
    "ellipse"       : "",
    "ellipsedict"   : "",
    "eofill"        : "",
    "exch"          : "",
    "fill"          : "",
    "findfont"      : "",
    "flattenpath"   : "",
    "grestore"      : "",
    "gsave"         : "",
    "initmatrix"    : "",
    "lineto"        : "",
    "matrix"        : "",
    "moveto"        : "",
    "newpath"       : "",
    "readhexstring" : "",
    "rlineto"       : "",
    "rmoveto"       : "",
    "rotate"        : "",
    "savematrix"    : "",
    "scale"         : "",
    "scalefont"     : "",
    "setdash"       : "",
    "setfont"       : "",
    "setlinecap"    : "",
    "setlinejoin"   : "",
    "setlinewidth"  : "",
    "setmatrix"     : "",
    "setmiterlimit" : "",
    "setrgbcolor"   : "",
    "show"          : "",
    "showpage"      : "",
    "stroke"        : "",
    "translate"     : "",
}

if translate_PS == yes:
    # Set the values to single letters
    value = ord('A')
    for key in ps.keys():
        ps[key] = chr(value)
        value = value + 1
        if value == ord('Z'):
            value = ord('a')
else:
    # Use the full Postscript names
    for key in ps.keys():
        ps[key] = key

# The INV dictionary will contain a mapping from integer value to the
# constant's name.  This will help with debugging output by giving
# symbolic names, rather than integers.

INV = {}

g = globals()
for key in g.keys():
    if type(g[key]) == type(0):
        INV[g[key]] = key
    elif type(g[key]) == type((0,)) and len(g[key]) == 3:  # A color tuple
        INV[g[key]] = key
del g

#-----------------------------------------------------------------------------
# The following chunks of Postscript are used as needed by the program.
# Note they aren't output unless functions that use them are called.

# Code to draw an ellipse.  From the Blue Book, pg. 137.

ellipse_ps = '''
    /edct 8 dict def edct /mtrx matrix put /ellipse { edct begin /ea
    exch def /sa exch def /md exch def /Md exch def /y exch def /x exch
    def /sm mtrx currentmatrix def newpath x y translate Md 2 div md 2
    div scale 0 0 1 sa ea arc sm setmatrix end } def
'''

# This is code to put text in a circle, from the Adobe Blue Book, pg 167
# (names were shortened).

circ_text_ps = '''
    % Text on a circular path
    /outsidecircletext
    { circtextdict
      begin
        /radius exch def
        /centerangle exch def
        /ptsize exch def
        /str exch def
        /xradius radius ptsize 4 div add def
        gsave
          centerangle str findhalfangle add rotate
          str
            { /charcode exch def
              ( ) dup 0 charcode put outsideplacechar
            } forall
        grestore
      end
    } def

    /insidecircletext
    { circtextdict
      begin
        /radius exch def
        /centerangle exch def
        /ptsize exch def
        /str exch def
        /xradius radius ptsize 3 div add def
        gsave
          centerangle str findhalfangle sub rotate
          str
            { /charcode exch def
              ( ) dup 0 charcode put insideplacechar
            } forall
        grestore
      end
    } def

    /circtextdict 16 dict def
    circtextdict
      begin
        /findhalfangle  {
          stringwidth pop 2 div
          2 xradius mul pi mul div 360 mul
        } def
        /outsideplacechar {
          /char exch def
          /halfangle char findhalfangle def
          gsave
            halfangle neg rotate
            radius 0 translate
            -90 rotate
            char stringwidth pop 2 div neg 0 moveto
            char show
          grestore
          halfangle 2 mul neg rotate
        } def

        /insideplacechar {
          /char exch def
          /halfangle char findhalfangle def
          gsave
            halfangle rotate
            radius 0 translate
            90 rotate
            char stringwidth pop 2 div neg 0 moveto
            char show
          grestore
          halfangle 2 mul rotate
        } def
        /pi 3.1415926 def
      end
'''

# From Adobe Blue Book pg 171:  Postscript code to print text along a path

path_text_ps = '''
    /pathtextdict 26 dict def
    /pathtext
    { pathtextdict begin
        /offset exch def
        /str exch def
        /pathdist 0 def
        /setdist offset def
        /charcount 0 def
        gsave
          flattenpath
          {movetoproc} {linetoproc}
          {curvetoproc} {closepathproc}
          pathforall
        grestore
        newpath
      end
    } def
    pathtextdict begin
    /movetoproc {
      /newy exch def /newx exch def
      /firstx newx def /firsty newy def
      /ovr 0 def
      newx newy transform
      /cpy exch def /cpx exch def
    } def
    /linetoproc {
      /oldx newx def /oldy newy def
      /newy exch def /newx exch def
      /dx newx oldx sub def
      /dy newy oldy sub def
      /dist dx dup mul dy dup mul add sqrt def
      dist 0 ne {
        /dsx dx dist div ovr mul def
        /dsy dy dist div ovr mul def
        oldx dsx add oldy dsy add transform
        /cpy exch def /cpx exch def
        /pathdist pathdist dist add def
        { setdist pathdist le
          { charcount str length lt {setchar} {exit} ifelse }
          { /ovr setdist pathdist sub def exit } ifelse
        } loop
      } if
    } def
    /curvetoproc {
      (ERROR:  no curveto's after a flattenpath!) print
    } def
    /closepathproc {
      firstx firsty linetoproc
      firstx firsty movetoproc
    } def
    /setchar {
      /char str charcount 1 getinterval def
      /charcount charcount 1 add def
      /charwidth char stringwidth pop def
      gsave
        cpx cpy itransform translate
        dy dx atan rotate
        0 0 moveto char show
        currentpoint transform
        /cpy exch def /cpx exch def
      grestore
      /setdist setdist charwidth add def
    } def
    end
'''

# From Adobe Blue Book pg 161:  Postscript code to print fractions
fraction_text_ps = '''
    /fractiondict 5 dict def
    /fractionshow {
      fractiondict begin
        /denominator exch def
        /numerator exch def
        /regularfont currentfont def
        /fractionfont currentfont [.65 0 0 .6 0 0] makefont def
        gsave
          newpath
            0 0 moveto
            (1) true charpath
          flattenpath pathbbox
          /height exch def pop pop pop
        grestore
        0 .4 height mul rmoveto
        fractionfont setfont numerator show
        0 .4 height mul neg rmoveto
        regularfont setfont (\244) show
        fractionfont setfont denominator show
        regularfont setfont
      end
    } def
'''

class Colors:
    def __init__(self):
        self.colors = \
'''aliceblue           darkolivegreen      lightgray           plum
antiquewhite        darkorange          lightgrey           plum1
aquamarine          darkorchid          lightpink           plum2
aquamarine1         darksalmon          lightsalmon         plum3
aquamarine2         darkseagreen        lightseagreen       plum4
aquamarine3         darkslateblue       lightskyblue        powderblue
aquamarine4         darkslategray       lightslateblue      purple
azure               darkslategrey       lightslategray      purple1
azure1              darkturquoise       lightslategrey      purple2
azure2              darkviolet          lightsteelblue      purple3
azure3              deeppink            lightyellow         purple4
azure4              deepskyblue         limegreen           red
beige               dimgray             linen               red1
bisque              dimgrey             magenta             red2
bisque1             dodgerblue          magenta1            red3
bisque2             firebrick           magenta2            red4
bisque3             firebrick1          magenta3            rosybrown
bisque4             firebrick2          magenta4            royalblue
black               firebrick3          maroon              saddlebrown
blanchedalmond      firebrick4          maroon1             salmon
blue                floralwhite         maroon2             salmon1
blue1               forestgreen         maroon3             salmon2
blue2               gainsboro           maroon4             salmon3
blue3               ghostwhite          mediumaquamarine    salmon4
blue4               gold                mediumblue          sandybrown
blueviolet          gold1               mediumforestgreen   seagreen
brown               gold2               mediumgoldenrod     seashell
brown1              gold3               mediumorchid        seashell1
brown2              gold4               mediumpurple        seashell2
brown3              goldenrod           mediumseagreen      seashell3
brown4              goldenrod1          mediumslateblue     seashell4
burlywood           goldenrod2          mediumspringgreen   sienna
burlywood1          goldenrod3          mediumturquoise     sienna1
burlywood2          goldenrod4          mediumvioletred     sienna2
burlywood3          green               midnightblue        sienna3
burlywood4          green1              mintcream           sienna4
cadetblue           green2              mistyrose           skyblue
chartreuse          green3              moccasin            slateblue
chartreuse1         green4              navajowhite         slategray
chartreuse2         greenyellow         navy                slategrey
chartreuse3         honeydew            navyblue            snow
chartreuse4         honeydew1           oldlace             snow1
chocolate           honeydew2           olivedrab           snow2
chocolate1          honeydew3           orange              snow3
chocolate2          honeydew4           orange1             snow4
chocolate3          hotpink             orange2             springgreen
chocolate4          indianred           orange3             steelblue
coral               ivory               orange4             tan
coral1              ivory1              orangered           tan1
coral2              ivory2              orchid              tan2
coral3              ivory3              orchid1             tan3
coral4              ivory4              orchid2             tan4
cornflowerblue      khaki               orchid3             thistle
cornsilk            khaki1              orchid4             thistle1
cornsilk1           khaki2              palegoldenrod       thistle2
cornsilk2           khaki3              palegreen           thistle3
cornsilk3           khaki4              paleturquoise       thistle4
cornsilk4           lavender            palevioletred       tomato
cyan                lavenderblush       papayawhip          tomato1
cyan1               lawngreen           peachpuff           tomato2
cyan2               lemonchiffon        peru                tomato3
cyan3               lightblue           pink                tomato4
cyan4               lightcoral          pink1               transparent
darkgoldenrod       lightcyan           pink2               turquoise
darkgreen           lightgoldenrod      pink3               turquoise1
darkkhaki           lightgoldenrodyello pink4               turquoise2
turquoise3          wheat1              white               yellow2
turquoise4          wheat2              whitesmoke          yellow3
violet              wheat3              yellow              yellow4
violetred           wheat4              yellow1             yellowgreen
wheat'''
    def __str__(self):
        return self.colors

# Print this object to get a nice listing of available colors
colors = Colors()

def GetVariableNames():
    '''Return a string representing the name of the variables that are
    represented by integers.
    '''
    # Check for any missing numbers (this might indicate a bug or
    # oversight above).
    k = varnames.keys()
    k.sort()
    for i in range(1, len(k)):
        if k[i - 1] + 1 != k[i]:
            raise ValueError("Discontinuity in varnames indexes at " + str(i))
    s = ""
    for i in varnames:
        s += "%3d %s\n" % (i, varnames[i])
    return s

